
#include <iostream>

template <typename T>
struct node
{
	node():m_Value(0),m_pNext(NULL){}

	T			 m_Value;
	struct node* m_pNext;
};

template<typename T>
class CLinkOp
{
public:
	typedef struct node<T> NodeType;

	CLinkOp(){}
	~CLinkOp(){}

	NodeType* Create()
	{
		return new NodeType;
	}

	void Clear(NodeType*& pHead)
	{
		NodeType* pNode = NULL;
		while(NULL != pHead)
		{
			pNode = pHead->m_pNext;
			delete pHead;
			pHead = pNode;			
		}
		pHead = NULL;
	}

	NodeType* GetTail(NodeType*& pHead)
	{
		NodeType* pTail = pHead;
		if (NULL != pTail)
		{
			while(NULL != pTail->m_pNext)
			{
				pTail = pTail->m_pNext;
			}
		}
		return pTail;
	}

	void Insert(NodeType*& pHead, NodeType* pNode)
	{
		NodeType* pTail = GetTail(pHead);
		if (NULL != pTail)
		{
			pTail->m_pNext = pNode;
		}
		else
		{
			pHead = pNode;
		}
	}

	void Remove(NodeType*& pHead, T tValue)
	{
		NodeType* pNode = pHead;
		while(NULL != pNode && pNode->m_Value == tValue)
		{
			pNode = pNode->m_pNext;
			pHead = pNode;
		}

		if (NULL != pNode)
		{
			NodeType* pNext = pNode->m_pNext;
			while(NULL != pNext)
			{
				if (pNext->m_Value == tValue)
				{
					pNode->m_pNext = pNext->m_pNext;
					delete pNext;
					pNext = NULL;
				}
				else
				{
					pNode = pNext;
				}

				if (NULL != pNode)
				{
					pNext = pNode->m_pNext;
				}
			}
		}		
	}

	void PrintLink(NodeType*& pHead)
	{
		NodeType* pNode = pHead;
		while(NULL != pNode)
		{
			std::cout << pNode->m_Value << " ";
			pNode = pNode->m_pNext;
		}
		std::cout << std::endl;
	}

	int GetLength(NodeType*& pHead)
	{
		int nLength = 0;
		NodeType* pNode = pHead;
		while(NULL != pNode)
		{
			pNode = pNode->m_pNext;
			++nLength;
		}
		return nLength;
	}

	NodeType* FindNode(NodeType*& pHead, T tValue)
	{
		NodeType* pNode = pHead;		
		while(NULL != pNode)
		{
			if (pNode->m_Value == tValue)
			{
				break;
			}
			pNode = pNode->m_pNext;
		}
		return pNode;
	}
};

void Test_LinkOp()
{
	typedef int NodeType;

	CLinkOp<NodeType>* pLinkOp = new CLinkOp<NodeType>;
	struct node<NodeType>* pHead = pLinkOp->Create();

	struct node<NodeType>* pNode1 = pLinkOp->Create();
	pNode1->m_Value = 0.1232;
	pLinkOp->Insert(pHead, pNode1);

	pLinkOp->PrintLink(pHead);
	std::cout << "length: " << pLinkOp->GetLength(pHead) << std::endl;

	struct node<NodeType>* pNode = pLinkOp->FindNode(pHead, 0.1232);
	if (NULL != pNode)
	{
		std::cout << "Find!" << std::endl;
	}
	pLinkOp->Clear(pHead);
}
